package com.huangwenshuo.futurestarschoolmanagement.service.impl;


import com.huangwenshuo.futurestarschoolmanagement.config.RedisService;
import com.huangwenshuo.futurestarschoolmanagement.exception.CustomRuntimeException;
import com.huangwenshuo.futurestarschoolmanagement.mapper.UsersMapper;
import com.huangwenshuo.futurestarschoolmanagement.pojo.dto.UserDto;
import com.huangwenshuo.futurestarschoolmanagement.pojo.enums.RequestStateEnum;
import com.huangwenshuo.futurestarschoolmanagement.pojo.po.UsersPo;
import com.huangwenshuo.futurestarschoolmanagement.pojo.vo.Result;
import com.huangwenshuo.futurestarschoolmanagement.pojo.vo.UserInfoVo;
import com.huangwenshuo.futurestarschoolmanagement.pojo.vo.UsersVo;
import com.huangwenshuo.futurestarschoolmanagement.service.RolesService;
import com.huangwenshuo.futurestarschoolmanagement.service.UsersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huangwenshuo.futurestarschoolmanagement.utils.DateTimeUtils;
import com.huangwenshuo.futurestarschoolmanagement.utils.ResUtils;
import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author huangwenshuo
 * @since 2020-12-26
 */
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, UsersPo> implements UsersService {

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private RolesService rolesService;

    @Autowired
    @Lazy
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private RedisService redisService;

    @Override
    @Transactional
    public void register(UserDto.RegisterUser registerUser) {
        if(registerUser.getRole() == null){
           registerUser.setRole("学生");
        }
        List<UsersVo> usersVos1 =usersMapper.findUsers(registerUser.getRealName(),registerUser.getPhone());
        if(usersVos1.size() != 0){
            throw new CustomRuntimeException("该用户已经存在");
        }
        registerUser.setPassword(bCryptPasswordEncoder.encode(registerUser.getPassword()));
        usersMapper.register(registerUser);
        List<UsersVo> usersVos2 =usersMapper.findUsers(registerUser.getRealName(),registerUser.getPhone());
        rolesService.addRole(usersVos2.get(0).getUid(),registerUser.getRole());
    }



    @Override
    public UserInfoVo getUserInfo(Integer uid) {
        UserInfoVo userInfoVo = usersMapper.getUserInfo(uid);
        return userInfoVo;
    }

    @Override
    public List<UsersVo> findUsers(String realName, String phone) {
        return usersMapper.findUsers(realName,phone);
    }

    @Override
    public Result uploadRegister(MultipartFile uploadFile) {
        InputStream is;
        Workbook wb = null;
        boolean isExcel2003 = true;
        List<String> phones = new ArrayList<>();
        String fileName = uploadFile.getOriginalFilename();
        try {
            is = uploadFile.getInputStream();
            if (fileName.matches("^.+\\.(?i)(xlsx)$")) {
                isExcel2003 = false;
            }
            if (isExcel2003) {
                wb = new HSSFWorkbook(is);
            } else {
                wb = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        Sheet sheet = wb.getSheetAt(0);
        Row row = sheet.getRow(0);
        Map<String,Integer> rows = new HashMap<>();
        for(int i =0;i<row.getLastCellNum();i++){
            Cell cell = row.getCell(i);
            String val = (String) getCellValue(cell);
            rows.put(val,i);
        }
        List<UserDto.RegisterUser> registerUsers = new ArrayList<>();
        for (int i = 1; i <=sheet.getLastRowNum(); i++) {
            UserDto.RegisterUser registerUser = new UserDto.RegisterUser();
            System.out.println((String)getCellValue(sheet.getRow(i).getCell(rows.get("username"))));
            registerUser.setUsername((String)getCellValue(sheet.getRow(i).getCell(rows.get("username"))));
            registerUser.setPassword((String)getCellValue(sheet.getRow(i).getCell(rows.get("password"))));
            registerUser.setRealName((String)getCellValue(sheet.getRow(i).getCell(rows.get("realName"))));
            registerUser.setPhone((String)getCellValue(sheet.getRow(i).getCell(rows.get("phone"))));
            registerUser.setAvatar((String)getCellValue(sheet.getRow(i).getCell(rows.get("avatar"))));
            registerUser.setRole((String)getCellValue(sheet.getRow(i).getCell(rows.get("role"))));
            registerUsers.add(registerUser);
        }
//        new Thread() {
//            @Override
//            public void run() {
//                for(UserDto.RegisterUser registerUser : registerUsers){
//                    register(registerUser);
//                }
//            }
//        }.start();
        Map<String,Object> res = new HashMap<>();

        List<String> faillist = new ArrayList<>();
        for(UserDto.RegisterUser registerUser : registerUsers){
                    try {
                        register(registerUser);
                    }catch (CustomRuntimeException e){
                        e.printStackTrace();
                        faillist.add(registerUser.getRealName()+"-"+registerUser.getPhone()+"reson："+e.getMessage());
                    }
                }
        res.put("successNum",registerUsers.size()-faillist.size());
        res.put("failNum",faillist.size());
        res.put("failReson",faillist);
        return ResUtils.result(RequestStateEnum.SUCCESS.value(),res,"添加成功");
    }

    @Override
    public Result registerMore(List<UserDto.RegisterUser> registerUsers) {
        Map<String,Object> res = new HashMap<>();
        List<String> faillist = new ArrayList<>();
        for(UserDto.RegisterUser registerUser : registerUsers){
            try {
                register(registerUser);
            }catch (CustomRuntimeException e){
                e.printStackTrace();
                faillist.add(registerUser.getRealName()+"-"+registerUser.getPhone()+"reson："+e.getMessage());
            }
        }
        res.put("successNum",registerUsers.size()-faillist.size());
        res.put("failNum",faillist.size());
        res.put("failReson",faillist);
        return ResUtils.result(RequestStateEnum.SUCCESS.value(),res,"添加成功");
    }

    @Override
    public Result updateUserInfo(UserDto.updateUserInfo updateUserInfo) {
         usersMapper.updateUserInfo(updateUserInfo);
        return ResUtils.result(RequestStateEnum.SUCCESS.value(),"更新成功");
    }

    @Override
    public void updateUserPwd(UserDto.updateUserPwd updateUserPwd) {
        if(updateUserPwd.getUid() == null)
        {
            throw new CustomRuntimeException("参数uid为空");
        }
        Map<String,String> map = usersMapper.findPwdByUid(updateUserPwd.getUid());
        if(map.get("password") == null){
            throw new CustomRuntimeException("用户信息不存在");
        }
        if(!bCryptPasswordEncoder.matches(updateUserPwd.getCpwd(),map.get("password"))){
            throw new CustomRuntimeException("旧密码错误");
        }
        if(!updateUserPwd.getNpwd().equalsIgnoreCase(updateUserPwd.getRpwd())){
            throw new CustomRuntimeException("两次输入的密码不一致");
        }
        try {
            usersMapper.updatePwd(bCryptPasswordEncoder.encode(updateUserPwd.getNpwd()),updateUserPwd.getUid());
            redisService.del("fssm:"+map.get("username"));
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomRuntimeException("");
        }

    }

    /**
     * 获取sheet单元格的值
     * @param cell
     * @return
     */
    public Object getCellValue(Cell cell) {
        Object value = null;
        CellType cellType = cell.getCellType();
        if (cellType.equals(CellType.STRING)) {
            value = cell.getRichStringCellValue().getString();
        } else if (cellType.equals(CellType.NUMERIC)) {
            HSSFDataFormatter dataFormatter = new HSSFDataFormatter();
            value = dataFormatter.formatCellValue(cell);
        } else if (cellType.equals(CellType.BOOLEAN)) {
            value = cell.getBooleanCellValue();
        } else if (cellType.equals(CellType.BLANK)) {
            value = "";
        }
        return value;
    }
}
